package org.jsola.hr.provider;

import org.jsola.core.Page;
import org.jsola.hr.dto.WeChatBindFromOffAccountDTO;
import org.jsola.hr.dto.user.AddUserDTO;
import org.jsola.hr.dto.user.UpdateUserRoleDTO;
import org.jsola.hr.query.HrUserQuery;
import org.jsola.hr.vo.EmpLoginResultVO;
import org.jsola.hr.vo.HrRoleVO;
import org.jsola.hr.vo.HrUserVO;
import org.jsola.hr.vo.RecruitResultVO;
import org.jsola.user.core.TokenUser;
import org.jsola.user.dto.JwtTokenDTO;
import org.jsola.user.dto.PhoneNumberDTO;
import org.jsola.user.dto.RecruitWechatXcxLoginDTO;
import org.jsola.user.dto.UserAddDTO;
import org.jsola.user.dto.login.WechatWebLoginDTO;
import org.jsola.user.dto.login.WechatXcxLoginDTO;
import org.jsola.user.entity.*;
import org.jsola.user.query.LoginLogQuery;
import org.jsola.user.query.UserQuery;
import org.jsola.user.vo.SystemConfigVO;
import org.jsola.user.vo.UserListVO;
import org.jsola.user.vo.UserLoginVO;
import org.jsola.user.vo.UserVO;

import java.util.List;

/**
 * @author JanusMix
 */
public interface IUserProviderService {
    /**
     * 查询
     *
     * @param userQuery 查询条件
     * @return list
     */
    List<UserListVO> select(UserQuery userQuery);

    /**
     * 微信小程序登录
     *
     * @param wechatXcxLoginDTO wechatXcxLoginDTO
     * @return EmpLoginResultVO
     */
    EmpLoginResultVO wechatXcxLogin(WechatXcxLoginDTO wechatXcxLoginDTO);

    /**
     * 微信管理端小程序登录
     *
     * @param wechatXcxLoginDTO wechatXcxLoginDTO
     * @return EmpLoginResultVO
     */
    EmpLoginResultVO wechatXcxLoginForAdmin(WechatXcxLoginDTO wechatXcxLoginDTO);

    /**
     * 招聘微信小程序登录
     *
     * @param recruitWechatXcxLoginDTO 登录信息
     * @return EmpLoginResultVO
     */
    @Deprecated
    RecruitResultVO wechatRecruitLogin(RecruitWechatXcxLoginDTO recruitWechatXcxLoginDTO);

    /**
     * 招聘微信小程序登录
     *
     * @param recruitWechatXcxLoginDTO 登录信息
     * @return EmpLoginResultVO
     */
    RecruitResultVO wechatRecruitLogin2(RecruitWechatXcxLoginDTO recruitWechatXcxLoginDTO);


    /**
     * 从微信授权信息中 获取用户手机号
     *
     * @param wechatXcxLoginDTO 授权信息
     * @return 用户手机号
     */
    String getPhone(WechatXcxLoginDTO wechatXcxLoginDTO);

    /**
     * 微信web扫码登录
     *
     * @param wechatWebLoginDTO wechatWebLoginDTO
     * @return UserLoginVO
     */
    EmpLoginResultVO wechatWebLogin(WechatWebLoginDTO wechatWebLoginDTO);


    /**
     * 绑定微信并登录
     *
     * @param userId       用户id
     * @param terminalType 终端类型
     * @param unionId      unionId
     * @return UserLoginVO
     */
    UserLoginVO bindWechatAndLogin(String userId, String terminalType, String unionId);

    /**
     * 新增员工
     *
     * @param addUserDTO 用户DTO
     * @param tokenUser  当前登录用户
     * @return userVO
     */
    HrUserVO saveUser(AddUserDTO addUserDTO, TokenUser tokenUser);

    /**
     * 添加或更新甲方端用户时同步把这个用户添加到服务反馈消息通知的发送人里面
     *
     * @param hrRole              角色Id
     * @param selectGroupIdList   用工单位分组Id
     * @param selectCompanyIdList 用工单位Id
     * @param userId              用户Id
     * @param tokenUser           当前登录用户
     */
    void saveUserUpdateNotice(HrRoleVO hrRole, List<String> selectGroupIdList, List<String> selectCompanyIdList,
                              String userId, TokenUser tokenUser);

    /**
     * 新增渠道用户（只创建user不创建角色）
     *
     * @param addUserDTO 用户DTO
     * @param tokenUser  当前登录用户
     * @return userVO
     */
    UserVO saveChannelUser(AddUserDTO addUserDTO, TokenUser tokenUser);

    /**
     * 修改员工角色
     *
     * @param updateUserRoleDTO 修改用户DTO
     * @param tokenUser         当前登录用户
     */
    void updateUserRole(UpdateUserRoleDTO updateUserRoleDTO, TokenUser tokenUser);

    /**
     * 修改密码
     *
     * @param userId   用户id
     * @param password 密码
     * @return 更新行数
     */
    Integer updateUserPassword(String userId, String password, TokenUser tokenUser);

    /**
     * 查询用户列表(严禁多线程调用)
     *
     * @param groupId 业务id,可为null
     * @param siteId  当前登录用户站点id
     * @return list对象
     */
    @Deprecated
    List<HrUserVO> queryUserList(UserQuery userQuery, String groupId, String siteId);

    /**
     * 查询用户列表(严禁多线程调用)
     *
     * @param tokenUser 当前登录用户
     * @return list对象
     */
    List<HrUserVO> queryUserList(HrUserQuery hrUserQuery, TokenUser tokenUser);

    /**
     * 查询用户列表(严禁多线程调用) 权限小于自己
     *
     * @param subjectId 业务id,可为null
     * @param tokenUser 当前登录用户
     * @return list对象
     */
    List<HrUserVO> queryUserListLessToMe(HrUserQuery hrUserQuery, String subjectId, TokenUser tokenUser);

    /**
     * 分页查询权限小于自己的用户
     *
     * @param hrUserQuery 查询条件
     * @param tokenUser   当前用户
     * @return 用户列表
     */
    Page<HrUserVO> pageUserListLessToMe(HrUserQuery hrUserQuery, TokenUser tokenUser);

    /**
     * 添加超级管理员
     *
     * @param result    被添加列表
     * @param tokenUser 当前用户
     */
    void addSuperAdmin(List<HrUserVO> result, TokenUser tokenUser);

    /**
     * 根据分公司id获取分公司名称
     *
     * @param childCompanyId 分公司id
     * @param siteId         站点id
     * @return 分公司名称
     */
    String getChildCompanyName(String childCompanyId, String siteId);

    /**
     * 查询拥有某公司权限的用户列表
     *
     * @param userQuery 查询参数
     * @param companyId 公司id
     * @param tokenUser 当前登录用户
     * @return list对象
     */
    List<HrUserVO> listUserHasRoleInCompany(UserQuery userQuery, String companyId, TokenUser tokenUser);

    /**
     * 查询拥有某租户权限的用户列表 不包含已删除的
     *
     * @param userQuery 查询参数
     * @param tokenUser 当前登录用户
     * @return list对象
     */
    List<HrUserVO> listUserHasRoleInSite(UserQuery userQuery, TokenUser tokenUser);

    /**
     * 查询拥有某公司权限的用户列表(分页)
     *
     * @param userQuery 查询参数
     * @param companyId 公司id
     * @param tokenUser 当前登录用户
     * @return list对象
     */
    Page<HrUserVO> pageUserHasRoleInCompany(UserQuery userQuery, String companyId, TokenUser tokenUser);


    /**
     * 查询拥有某租户权限的用户列表(分页)
     *
     * @param userQuery 查询参数
     * @param tokenUser 当前登录用户
     * @return list对象
     */
    Page<HrUserVO> pageUserHasRoleInSite(UserQuery userQuery, TokenUser tokenUser);

    /**
     * 查询拥有某公司权限的用户列表
     *
     * @param companyId 公司id
     * @param tokenUser 当前登录用户
     * @return list对象
     */
    List<HrUserVO> selectUserHasRoleInCompany(String companyId, TokenUser tokenUser);

    /**
     * 查询拥有某公司权限的用户id
     *
     * @param companyId 公司id
     * @param tokenUser 当前登录用户
     * @return list对象
     */
    List<String> selectUserIdHasRoleInCompany(String companyId, TokenUser tokenUser);

    /**
     * 查询拥有某公司下员工对应用户及能管理该公司的用户列表
     *
     * @param companyId 公司id
     * @param userQuery 查询参数
     * @param tokenUser 当前登录用户
     * @return list对象
     */
    List<HrUserVO> listEmpAndRoleUserInCompany(UserQuery userQuery, String companyId, TokenUser tokenUser);


    /**
     * 查询拥有某公司下员工对应用户及能管理该公司的用户列表
     *
     * @param companyId 公司id
     * @param userQuery 查询参数
     * @param tokenUser 当前登录用户
     * @return list对象
     */
    Page<HrUserVO> pageEmpAndRoleUserInCompany(UserQuery userQuery, String companyId, TokenUser tokenUser);

    /**
     * 查询简单用户列表
     *
     * @param userQuery 查询对象
     * @param siteId    当前登录用户站点id
     * @return list对象
     */
    Page<HrUserVO> querySimpleUserPage(UserQuery userQuery, String siteId);

    /**
     * 离职员工
     *
     * @param userIds   用户id
     * @param tokenUser 当前登录用户
     */
    void dimissionUser(String[] userIds, TokenUser tokenUser);

    /**
     * 恢复在职员工
     *
     * @param userId    用户id
     * @param tokenUser 当前登录用户
     */
    void recoverUser(String userId, TokenUser tokenUser);

    /**
     * 删除员工
     *
     * @param userIds   用户id
     * @param tokenUser 当前登录用户
     */
    void deleteUser(String[] userIds, TokenUser tokenUser);

    /**
     * 查询用户信息 user单表查询，不包含站点和用户状态信息
     *
     * @param userId userId
     * @return UserDO
     */
    UserDO selectUserById(String userId);

    /**
     * 查询用户信息 user单表查询，不包含站点和用户状态信息
     *
     * @param userIds userId
     * @return UserDO
     */
    List<UserDO> selectUserByIds(List<String> userIds);

    /**
     * 查询用户信息 user单表查询，不包含站点和用户状态信息
     *
     * @param phone 手机号
     * @return UserDO
     */
    UserDO selectByPhone(String phone);


    /**
     * 仅保存用户
     *
     * @param userAddDTO 用户信息
     * @return 用户信息
     */
    UserVO onlySaveUser(UserAddDTO userAddDTO);

    /**
     * 保存用户及站点信息 默认站点不保存
     *
     * @param userAddDTO 用户信息
     * @param tokenUser  登陆当前用户
     * @return 用户信息
     */
    UserVO saveUserAndSite(UserAddDTO userAddDTO, TokenUser tokenUser);

    /**
     * 员工注册账号
     *
     * @param name      用户名
     * @param phone     电话
     * @param tokenUser 登陆当前用户
     * @param companyId 公司Id
     * @return 用户对象
     */
    UserVO registerAccount(String name, String phone, TokenUser tokenUser, String companyId);

    /**
     * 根据用户id查询第三方信息
     *
     * @param appId  公众号/小程序appId
     * @param userId 用户id
     * @return 第三方信息
     */
    ThirdInfoDO selectThirdInfoByUserId(String appId, String userId);

    /**
     * 修改用户绑定手机号
     *
     * @param userId    用户id
     * @param oldPhone  修改前手机号
     * @param newPhone  修改后手机号
     * @param tokenUser 当前登录用户
     */
    void updateUserPhone(String userId, String oldPhone, String newPhone, TokenUser tokenUser);

    /**
     * 将用户添加到当前租户
     *
     * @param userId    用户id
     * @param tokenUser 当前登录用户
     */
    void saveUserSite(String userId, TokenUser tokenUser);

    /**
     * 获取用户unionId和openId关联对象
     *
     * @param appId   用户id
     * @param unionId 手机号
     */
    UnionOpenIdDO getUnionOpenIdDO(String appId, String unionId, String userId);

    /**
     * 公众号跳转小程序绑定微信
     *
     * @param weChatBindFromOffAccountDTO 公众号跳转小程序绑定微信的参数
     */
    Boolean bindWeChatFromOfficialAccount(WeChatBindFromOffAccountDTO weChatBindFromOffAccountDTO);

    /**
     * 更新用户拼音
     */
    void updateAllUserPinyin();

    /**
     * 获取用户unionId和openId关联对象
     *
     * @param userId 用户id
     */
    UnionOpenIdDO getUnionOpenByUserId(String appId, String userId);


    /**
     * 某用户有权限的分公司
     *
     * @param userId 用户id
     * @param siteId 站点id
     * @return 某用户有权限的分公司
     */
    List<String> listChildCompanyByUser(String userId, String siteId);

    /**
     * 根据unionId查询第三方信息
     *
     * @param unionId unionId
     * @return 第三方信息对象
     */
    ThirdInfoDO selectByUnionId(String unionId);

    /**
     * 切换租户token
     *
     * @param token  token
     * @param siteId 要切换的站点id
     * @return token
     */
    JwtTokenDTO switchToken(String token, String siteId);

    /**
     * 注册一个用户
     *
     * @param name  用户名
     * @param phone 电话
     * @return 用户
     */
    UserVO registerUser(String name, String phone);


    /**
     * 查询用户（微信）信息
     *
     * @param userId 用户Id
     * @return 用户（微信）信息
     */
    ThirdInfoDO selectUserSettingById(String userId);

    /**
     * 查询用户（微信）信息
     *
     * @param userIds 用户Ids
     * @return 用户（微信）信息
     */
    List<ThirdInfoDO> selectUserSettingByIds(List<String> userIds);


    /**
     * 用户解绑微信
     *
     * @param userId 用户Id
     */
    void unbindWechatByUserId(String userId);

    /**
     * 根据unionId, openId,appId查询唯一记录
     *
     * @param unionId unionId
     * @param openId  openId
     * @param appId   appId
     * @return unionId和openId关联信息列表信息
     */
    UnionOpenIdDO selectByUnionIdAndOpenIdAndAppId(String unionId, String openId, String appId);

    /**
     * 根据unionId, openId,appId删除唯一记录
     *
     * @param unionId unionId
     * @param openId  openId
     * @param appId   appId
     * @return 删除数量
     */
    int deleteByUnionIdAndOpenIdAndAppId(String unionId, String openId, String appId);

    /**
     * 根据openId查询记录,用于取消关注公众号查询记录
     *
     * @param openId openId
     * @return unionId和openId关联信息列表信息
     */
    List<UnionOpenIdDO> selectByOpenId(String openId);

    /**
     * 根据openId删除unionOpenId记录
     *
     * @param openId openId
     * @return 删除数量
     */
    int deleteByOpenId(String openId);

    /**
     * 根据凭证更换手机号
     *
     * @param voucher   凭证
     * @param phone     新手机号
     * @param code      验证码，场景是UserConstants.COMMON_SCENE
     * @param tokenUser 当前登录用户
     */
    UserDO updatePhoneByVoucher(String voucher, String phone, String code, TokenUser tokenUser);

    /**
     * 调用通用服务验证验证码，携带当前登录用户信息
     *
     * @param code      验证码
     * @param phone     手机号
     * @param scene     场景
     * @param tokenUser 当前登录用户
     * @return bool对象
     * @since 1.2
     */
    Boolean checkCodeWithUser(String code, String phone, String scene, TokenUser tokenUser);


    /**
     * 获取域名的系统配置
     *
     * @param domain 域名
     * @return 系统配置
     */
    SystemConfigVO selectSystemConfigByDomain(String domain);


    /**
     * 根据用户id查询用户站点信息，在职的
     *
     * @param userId 用户id
     * @return 用户站点列表
     */
    List<UserSiteDO> selectUserSiteByUserId(String userId);


    /**
     * 批量删除用户拥有的站点，物理删除，更新is_valid字段，从回收站删除
     *
     * @param tokenUser   当前用户
     * @param userSiteIds 用户拥有的站点id
     * @return 删除数量
     */
    int deleteUserSiteByIds(TokenUser tokenUser, Long... userSiteIds);


    /**
     * 解密用户手机号信息.
     *
     * @param wechatXcxLoginDTO 用户的加密信息
     * @param deviceType        设备类型
     * @return .
     */
    PhoneNumberDTO getPhoneNoInfo(WechatXcxLoginDTO wechatXcxLoginDTO, String deviceType);


    /**
     * 分页查询用户登录日志 跨站点
     *
     * @param loginLogQuery 查询条件
     * @return 用户登录日志列表信息
     */
    Page<LoginLogDO> loginLogPageNotSiteId(LoginLogQuery loginLogQuery);

    /**
     * 根据用户id查询用户站点信息，在职的
     *
     * @param userId 用户id
     * @return 用户站点列表
     */
    List<UserSiteDO> selectByUserId(String userId);

    /**
     * 查询openId，根据unionId和appId
     *
     * @param unionId unionId
     * @param appId   appId
     * @return DO
     */
    UnionOpenIdDO selectOpenId(String unionId, String appId);

    /**
     * 根据userId 查询openid
     *
     * @param userId    用户id
     * @param tokenUser 当前用户
     * @return openid
     */
    public String selectOpenIdByUserId(String userId, TokenUser tokenUser);

    /**
     * 根据userId 及 appid 查询openid
     *
     * @param userId    用户id
     * @param appId     appId
     * @param tokenUser 当前用户
     * @return openid
     */
    public String selectOpenIdByUserIdAndAppId(String userId, String appId, TokenUser tokenUser);

    /**
     * 根据userId查询用户信息
     *
     * @param userId 用户id
     * @return 用户信息
     */
    UserVO selectById(String userId);

    /**
     * 获取用户unionId和openId关联对象
     *
     * @param userId 用户id
     * @param appId  公众号appid
     */
    UnionOpenIdDO getUnionOpenIdByUser(String userId, String appId);

    /**
     * 查询甲方用户列表(严禁多线程调用) 权限小于自己
     *
     * @param hrUserQuery 查询参数
     * @param subjectId   业务id,可为null
     * @param tokenUser   当前登录用户
     * @return list对象
     */
    List<HrUserVO> queryUserJiaFang(HrUserQuery hrUserQuery, String subjectId, TokenUser tokenUser);
}
